package com.jufa_3.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jufa_3.dto.ComboCostInfo;
import com.jufa_3.dto.SelectInfo;
import com.jufa_3.entity.ChargeRecord;
import com.jufa_3.entity.ComboOrder;
import com.jufa_3.mapper.ChargeRecordMapper;
import com.jufa_3.mapper.ComboOrderMapper;
import com.jufa_3.service.ComboOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ComboOrderServiceImpl extends ServiceImpl<ComboOrderMapper, ComboOrder> implements ComboOrderService {

    @Autowired
    private ComboOrderService comboOrderService;

    @Autowired
    private ChargeRecordMapper chargeRecordMapper;

    @Override
    @Transactional
    public Integer debit(SelectInfo sif) {
        Float debitNum = sif.getFee();
        List<ComboOrder> comboOrderList = comboOrderService.lambdaQuery()
                .eq(ComboOrder::getOpenId, sif.getOpenId())
                .eq(ComboOrder::getEnable, "1")
                .gt(ComboOrder::getSurpulsValue, 0.0f)
                .orderByDesc(ComboOrder::getBuyPrice)
                .orderByAsc(ComboOrder::getBuyTime).list();
        boolean isEnd = false;
        Map<String, Float> comboSurplusMap = new HashMap<>();
        // 依次扣费
        for (int i = 0; i < comboOrderList.size(); i++) {
            ComboOrder item = comboOrderList.get(i);
            if (item.getSurpulsValue() >= debitNum) {
                comboOrderService.update(new LambdaUpdateWrapper<ComboOrder>()
                        .eq(ComboOrder::getId, item.getId())
                        .setSql("surpuls_value=surpuls_value-" + debitNum));
                item.setSurpulsValue(item.getSurpulsValue() - debitNum);
                isEnd = true;
            } else {
                comboOrderService.update(new LambdaUpdateWrapper<ComboOrder>()
                        .eq(ComboOrder::getId, item.getId())
                        .set(ComboOrder::getSurpulsValue, 0));
                debitNum -= item.getSurpulsValue();
                item.setSurpulsValue(0f);
            }
            String key = item.getComboName();
            if (comboSurplusMap.containsKey(key)) {
                comboSurplusMap.put(key, comboSurplusMap.get(key) + item.getSurpulsValue());
            } else {
                comboSurplusMap.put(key, item.getSurpulsValue());
            }
            if (isEnd) {
                break;
            }
        }
        ChargeRecord cr = new ChargeRecord(sif.getOpenId(), sif.getCostName(), sif.getKeyWord(), sif.getFee());
        DecimalFormat df = new DecimalFormat("0.00");
        if (comboSurplusMap.size() == 1) {
            comboSurplusMap.forEach((key, value) -> {
                cr.setPayCombo(key);
                cr.setPayComboBalance(df.format(value));
            });
        } else {
            comboSurplusMap.forEach((key, value) -> {
                cr.setPayCombo(cr.getPayCombo() == null ? key : cr.getPayCombo() + ";" + key);
                cr.setPayComboBalance(cr.getPayComboBalance() == null ? key + ":" + df.format(value) : cr.getPayComboBalance() + ";" + key + ":" + df.format(value));
            });
        }
        if (cr.getPayCombo() == null || cr.getPayComboBalance() == null) {
            return -1;
        }
        // 添加收费记录
        chargeRecordMapper.addChargeRecord(cr);
        // 返回收费记录id
        return cr.getId();
    }

    @Override
    public ComboCostInfo getUserCombos(String openId, boolean isGtZero) {
        List<ComboOrder> comboOrderList = comboOrderService.lambdaQuery()
                .eq(ComboOrder::getOpenId, openId)
                .eq(isGtZero, ComboOrder::getEnable, "1")
                .gt(isGtZero, ComboOrder::getSurpulsValue, 0)
                .orderByDesc(ComboOrder::getBuyPrice)
                .orderByAsc(ComboOrder::getBuyTime).list();
        if (comboOrderList == null || comboOrderList.size() == 0) {
            return null;
        }
        // 汇总
        float total = 0;
        List<ComboOrder> comboOrderNomal = new ArrayList<>();
        float nomalTotal = 0;
        List<ComboOrder> comboOrderStaleDated = new ArrayList<>();
        float staleDatedTotal = 0;
        for (ComboOrder comboOrder : comboOrderList) {
            total += comboOrder.getSurpulsValue();
            // 过期分类
            if (comboOrder.getUseEndTime().isBefore(LocalDateTime.now())) {
                // 过期
                comboOrderStaleDated.add(comboOrder);
                staleDatedTotal += comboOrder.getSurpulsValue();
            } else {
                // 未过期
                comboOrderNomal.add(comboOrder);
                nomalTotal += comboOrder.getSurpulsValue();
            }
        }
        return new ComboCostInfo(total, nomalTotal, staleDatedTotal, comboOrderNomal, comboOrderStaleDated);
    }

    @Override
    public boolean without399Combo(String openId) {
        List<ComboOrder> comboOrderList = comboOrderService.lambdaQuery()
                .eq(ComboOrder::getOpenId, openId)
                .eq(ComboOrder::getComboName, "尊惠版套餐")
                .eq(ComboOrder::getEnable, "1")
                .gt(ComboOrder::getSurpulsValue, 0)
                .orderByAsc(ComboOrder::getBuyTime).list();
        if (comboOrderList == null || comboOrderList.size() == 0) {
            return true;
        }
        for (ComboOrder comboOrder : comboOrderList) {
            if (LocalDateTime.now().isBefore(comboOrder.getUseEndTime())) {
                // 未过期
                return false;
            }
        }
        return true;
    }

}
